import os
import json
import time
from typing import Optional
from langchain.tools import tool
import webbrowser
import psutil

from Impl.wav_impl import WavImpl
from config import FRONTEND_URL, DB_CONFIG

# 存储全局实例（需在使用工具前通过set方法传入有效实例）
_websocket_server = None
_voice_worker = None

"""设置WebSocket服务器实例（必须在使用工具前调用）"""
def set_websocket_server(websocket_server):
    global _websocket_server
    _websocket_server = websocket_server
    print(f"✅ 工具已绑定WebSocket服务器实例")

"""设置VoiceWorker实例（必须在使用工具前调用）"""
def set_voice_worker(voice_worker):
    global _voice_worker
    _voice_worker = voice_worker
    print(f"✅ 工具已绑定VoiceWorker实例")


@tool("open_browser", description="当用户要求打开浏览器时调用此工具，自动等待前端连接")
def open_browser() -> str:
    """打开浏览器窗口，并等待前端WebSocket连接完成"""
    global _websocket_server, _voice_worker

    # 1. 校验全局实例是否初始化
    if not _websocket_server:
        return "❌ 打开浏览器失败：WebSocket服务器未初始化"
    if not _voice_worker:
        return "❌ 打开浏览器失败：VoiceWorker实例未初始化"

    # 2. 获取当前用户信息（和VoiceWorker逻辑对齐）
    current_user = _voice_worker.current_user
    user_role = "访客"
    # 如果是已认证用户，尝试获取具体身份信息
    if _voice_worker.user_authenticated and current_user:
        try:
            from Impl.user_title_impl import UserTitleImpl
            from Impl.wav_impl import WavImpl
            from config import DB_CONFIG
            
            # 首先获取用户ID
            with WavImpl(DB_CONFIG) as wav_impl:
                wav_files = wav_impl.get_wav_by_user_english_name(current_user)
                if wav_files:
                    db_user_id = wav_files[0].id
                    
                    # 然后获取用户的所有业务身份
                    with UserTitleImpl(DB_CONFIG) as user_title_impl:
                        user_titles = user_title_impl.get_titles_by_user_id(db_user_id)
                        
                        if user_titles:
                            # 如果用户有多个身份，组合显示
                            roles = [f"{title.title_name}({title.level})" for title in user_titles]
                            user_role = "、".join(roles)
                        else:
                            user_role = "已认证用户"
                else:
                    user_role = "已认证用户"
        except Exception as e:
            print(f"⚠️ 获取用户详细身份信息时出错: {e}")
            user_role = "已认证用户"
    elif _voice_worker.user_authenticated:
        user_role = "已认证用户"

    # 3. 打印用户登录信息（和原有流程一致）
    if current_user:
        print(f"👨‍💻 {user_role} {current_user} 触发打开浏览器")
    else:
        print(f"👤 游客触发打开浏览器")

    # 4. 检查网页是否已打开（复用原有逻辑）
    url_identifier = FRONTEND_URL.split("//")[-1].split("?")[0].rstrip('/')
    print(f"🌍 检查网页 [{url_identifier}] 是否已打开...")

    browser_process_names = {
        "chrome.exe", "msedge.exe", "firefox.exe", "opera.exe",  # Windows
        "chrome", "chromium", "firefox", "opera", "edge"  # Linux/macOS
    }
    page_already_open = False

    try:
        for proc in psutil.process_iter(["name", "cmdline"]):
            proc_name = proc.info.get("name", "").lower()
            if not any(browser in proc_name for browser in browser_process_names):
                continue

            cmdline = proc.info.get("cmdline", [])
            if not cmdline:
                continue

            for arg in cmdline:
                if url_identifier in arg:
                    page_already_open = True
                    print(f"✅ 检测到网页已在进程 [{proc_name}] 中打开")
                    break
            if page_already_open:
                break
    except psutil.AccessDenied:
        print("⚠️ 无权限访问进程信息，无法准确判断网页状态")
    except Exception as e:
        print(f"⚠️ 检查进程时出错：{str(e)}")

    # 5. 打开网页（未打开则启动浏览器）
    if not page_already_open:
        print(f"🌍 网页未打开，正在唤醒：{FRONTEND_URL}")
        try:
            success = webbrowser.open_new(FRONTEND_URL)
            if not success:
                return f"❌ 唤醒浏览器失败，请手动访问：{FRONTEND_URL}"
        except Exception as e:
            return f"❌ 打开浏览器出错：{str(e)}"
    else:
        print(f"🌍 网页已打开，无需重复唤醒")

    # 6. 等待前端连接（关键：和VoiceWorker流程对齐）
    if _wait_for_frontend_connection():
        # 连接成功后，同步发送用户身份信息（复用VoiceWorker逻辑）
        identity_message = {
            "type": "user_info",
            "user_id": current_user if current_user else "guest",
            "user_role": user_role,
            "timestamp": time.time()
        }
        _websocket_server.send_message(json.dumps(identity_message))
        return f"✅ 浏览器操作完成：{'已打开网页' if not page_already_open else '网页已打开'}，前端已连接并同步用户身份"
    else:
        return f"⚠️ 浏览器操作完成，但前端未在{_wait_for_frontend_connection.__defaults__[0]}秒内连接"


@tool("send_message_to_frontend", description="用户提到向Web前端发送消息内容，自动检查连接状态")
def send_message_to_frontend(text: str, user_id: Optional[str] = None, user_role: str = "访客") -> str:
    """发送消息到前端，先检查连接状态，未连接则尝试等待"""
    global _websocket_server
    if not _websocket_server:
        return "❌ 发送消息失败：WebSocket服务器未初始化"

    # 1. 检查当前连接状态，未连接则尝试等待
    with _websocket_server.client_lock:
        clients = _websocket_server.connected_clients.copy()
    if not clients:
        print("⚠️ 当前无前端连接，尝试等待连接...")
        if not _wait_for_frontend_connection(timeout=3):  # 短超时等待
            return "❌ 发送消息失败：无前端连接"

    # 2. 构造消息（和VoiceWorker消息格式对齐）
    message = {
        "type": "message",
        "text": text,
        "user_id": user_id if user_id else "guest",
        "user_role": user_role,
        "timestamp": time.time()
    }

    # 3. 发送消息（沿用WebSocketServer的线程安全发送逻辑）
    try:
        _websocket_server.send_message(json.dumps(message))
        print(f"📤 工具已发送消息：{text}")
        return f"✅ 消息已成功发送到前端：{text}"
    except Exception as e:
        return f"❌ 发送消息到前端失败：{str(e)}"


@tool("get_connected_clients_count", description="用户提到获取当前连接到WebSocket服务器的客户端数量")
def get_connected_clients_count() -> str:
    """获取当前连接的客户端数量（带锁保护，线程安全）"""
    global _websocket_server
    if not _websocket_server:
        return "❌ 获取连接数失败：WebSocket服务器未初始化"

    try:
        with _websocket_server.client_lock:
            clients = _websocket_server.connected_clients.copy()
        count = len(clients)
        print(f"📊 当前前端连接数：{count}")
        return f"✅ 当前连接到WebSocket服务器的客户端数量为：{count}"
    except Exception as e:
        error_msg = f"获取连接客户端数量失败：{str(e)}"
        print(f"❌ {error_msg}")
        return f"❌ {error_msg}"


def _wait_for_frontend_connection(timeout=5) -> bool:
    global _websocket_server
    if not _websocket_server:
        print("⚠️ 等待连接失败：WebSocket服务器未初始化")
        return False

    start_time = time.time()
    print(f"⌛ 等待前端连接（超时{timeout}秒）...")
    while time.time() - start_time < timeout:
        # 沿用WebSocketServer的锁保护逻辑，获取客户端集合
        with _websocket_server.client_lock:
            clients = _websocket_server.connected_clients.copy()
        if clients:
            print(f"✅ 前端已连接，当前连接数：{len(clients)}")
            return True
        time.sleep(0.5)  # 每隔0.5秒检查一次

    print("❌ 等待连接超时：前端未在规定时间内连接")
    return False